package com.rede.didiok.sms.event;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rede.didiok.common.convert.AggEsDocConvert;
import com.rede.didiok.common.domainEvent.DomainEvent;
import com.rede.didiok.common.domainEvent.EntityType;
import com.rede.didiok.common.dto.community.UserMomentDto;
import com.rede.didiok.common.dto.user.UserDto;
import com.rede.didiok.common.enums.AuditStatusEnum;
import com.rede.didiok.common.enums.BusinessTypeEnum;
import com.rede.didiok.common.enums.OperateEnum;
import com.rede.didiok.common.enums.PublishEnum;
import com.rede.didiok.common.exception.exceptionType.FeignException;
import com.rede.didiok.common.schema.AggEsDoc;
import com.rede.didiok.common.utils.R;
import com.rede.didiok.common.utils.StringUtils;
import com.rede.didiok.sms.event.annotation.EventType;
import com.rede.didiok.sms.event.service.AbstractEventHandler;

/**
 * 动态事件处理器
 *
 * @author 陌溪
 * @date 2022年12月16日20:49:18
 */
@Slf4j
@Component
@EventType({EntityType.MOMENT})
public class MomentEventHandler extends AbstractEventHandler {

    @Override
    public void doEventHandler(DomainEvent domainEvent) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        UserMomentDto userMoment = objectMapper.convertValue(domainEvent.getEntity(), UserMomentDto.class);
        switch (domainEvent.getEventAction()) {
            case MOMENT_ADD: {
                this.add(userMoment, domainEvent.isAdminOperate());
            }
            break;
            case MOMENT_EDIT: {
                this.edit(userMoment, domainEvent.isAdminOperate());
            }
            break;
            case MOMENT_DELETE: {
                this.delete(userMoment, domainEvent.isAdminOperate());
            }
            break;
            case MOMENT_AUDIT: {
                this.audit(userMoment, domainEvent.isAdminOperate());
            }
            break;
        }
    }

    /**
     * 动态审核事件
     *
     * @param userMoment
     * @param isAdminOperate
     */
    public void audit(UserMomentDto userMoment, boolean isAdminOperate) {
        /**
         * 发送邮件
         */
        if (userMoment.getCreateUserUid() != null) {
            R result = userFeignClient.getUserById(userMoment.getCreateUserUid());
            UserDto user;
            if(result.getCode()==0){
                user = result.getData(new TypeReference<UserDto>(){});
            }else {
                // 获取异常信息
                throw new FeignException("feign调用异常（根据用户id找用户）：失败");
            }
            StringBuilder text = new StringBuilder();
            text.append(String.format("<p>可爱的博主%s,您的动态</p>", user.getNickname()));
            if (AuditStatusEnum.REJECT.equals(userMoment.getAuditStatus())) {
                text.append("审核未通过,审核原因为" + userMoment.getRejectReason());
                rabbitMqUtil.sendSimpleEmail(user.getEmail(), text.toString());
            } else if (AuditStatusEnum.AGREE.equals(userMoment.getAuditStatus())) {
                text.append("审核已通过");
                rabbitMqUtil.sendSimpleEmail(user.getEmail(), text.toString());
            } else {
                log.error("审核状态异常,稿件为{}", userMoment.getUid());
            }
        }
        this.syncAggEsDoc(userMoment, OperateEnum.EDIT);
    }

    /**
     * 新增事件
     *
     * @param userMoment
     * @param isAdminOperate
     */
    public void add(UserMomentDto userMoment, boolean isAdminOperate) {
        if (AuditStatusEnum.AGREE.equals(userMoment.getAuditStatus()) && PublishEnum.PUBLISH.equals(userMoment.getIsPublish())) {
            // 通知关注的用户，发送动态通知
            asyncService.executeAsyncBusinessNotice(false, userMoment.getCreateUserUid(), userMoment.getUid(), BusinessTypeEnum.MOMENT.getCode());
        }

        String atUserUid = StringUtils.getAtUserUid(userMoment.getContent());
        ;
        // 判断是否触发AT功能，触发AT后的动作
        if (StringUtils.isNotEmpty(atUserUid)) {
            atEventHandler.atEventHandler(userMoment.getCreateUserUid(), atUserUid, userMoment.getUid(), "USER_MOMENT", userMoment.getContent());
        }

        // 发送后台站内信通知
        asyncService.executeAsyncBusinessBlackNotice(false, userMoment.getCreateUserUid(), userMoment.getUid(), BusinessTypeEnum.MOMENT.getCode(), userMoment.getContent());
        // 更新ES索引
        this.syncAggEsDoc(userMoment, OperateEnum.ADD);
    }

    /**
     * 更新动态
     *
     * @param userMoment
     * @param isAdminOperate
     */
    public void edit(UserMomentDto userMoment, boolean isAdminOperate) {
        this.syncAggEsDoc(userMoment, OperateEnum.EDIT);
    }

    /**
     * 删除动态
     *
     * @param userMoment
     * @param isAdminOperate
     */
    public void delete(UserMomentDto userMoment, boolean isAdminOperate) {

        this.syncAggEsDoc(userMoment, OperateEnum.DELETE);
    }

    /**
     * syncAggEsDoc 同步到ES
     *
     * @param userMoment
     * @param operate
     */
    private void syncAggEsDoc(UserMomentDto userMoment, OperateEnum operate) {
        AggEsDoc aggEsDoc = AggEsDocConvert.convertMoment(userMoment);
        asyncService.executeAsyncUpdateEsAndRedis(aggEsDoc, operate);
    }
}
